﻿//
// Created by 抑~风 on 2022/10/26.
//



#ifndef CWJ_THREADPOOL_H
#define CWJ_THREADPOOL_H

#include <memory>
#include<thread>
#include<iostream>
#include <utility>
#include<vector>
#include<atomic>
#include<mutex>
#include<condition_variable>
#include<functional>
#include<unordered_map>
#include<queue>
#include<memory>
#include <cassert>

namespace CWJ {

    class Thread {

    public:
        // 类型成员
        using ThreadFunc = std::function<void()>;
        // 功能函数
        void start() ;
        uint32_t getUid() const;
        // 生命周期函数
        explicit Thread(ThreadFunc func);
        ~Thread();

        // 静态函数
        static uint32_t getNowId();

    private:
        // 为每个Thread生成编号
        static uint32_t nowId;
        // 线程函数
        ThreadFunc func;
        // 编号
        uint32_t uid ;
        // 真正的线程对象
        std::thread* td;
    };

    class CwjAny {
    public:

        CwjAny()  = default;

        template<typename T>
        CwjAny(T data) :data_(std::make_shared<Derive<T>>(data)){};

        template<typename T>
        void setData(T);

        template<typename T>
        T cast_();

    private:
        class Base;
        template<typename T>
        class Derive;
        // 存储数据
        std::shared_ptr<Base> data_;
    };
    // CwjAng中的私有类
    class CwjAny::Base {
    public:
        virtual ~Base() = default;
    };

    // CwjAng中的私有类
    template<typename T>
    class CwjAny::Derive : public CwjAny::Base {
    public:
        explicit Derive(T d) : data_(d) {};
        T getData() { return data_; };
    private:
        T data_;
    };

    // 信号量
    class CwjSemaphore {
    public:
        // 功能函数

        void wait();
        void post();
        size_t getNum(){return this->src_num;};

        // 生命周期函数
        CwjSemaphore() = default;
        explicit CwjSemaphore(size_t src_num) : src_num(src_num){};

        CwjSemaphore(const CwjSemaphore&) = delete;
        CwjSemaphore(CwjSemaphore&&) = delete;
        ~CwjSemaphore() = default;
        CwjSemaphore& operator=(const CwjSemaphore&) = delete;

    private:
        std::mutex mx_lock;
        std::condition_variable cv;
        // 拥有的资源数
        volatile std::atomic<size_t> src_num{0};
    };

    template<typename T>
    class Result {
    public:
        // 功能函数
        T get();
        void set(const T&);
        void set(T&&);
        bool getValid();

        // 生命周期函数
        Result() = default;

    private:
        // 目前没有任何作用
        void setValid(bool isValid);

        T data_;
        volatile std::atomic_bool isValid{false};
        CwjSemaphore sem_sp;
        volatile std::atomic_bool isReady{false};
    };

    template<>
    class Result<void>{
    public:
        Result()= default;;
        bool getValid(){return false;};
    };

    template<typename Res_>
    class Task {
    public:
        // 可包装函数
        using Func = std::function<Res_()>;
        // 执行函数，并设置Result
        void exec();
        Task(Func func,std::shared_ptr<Result<Res_>> res):func(func),res(std::move(res)){};
        Task() = default;
    private:
        Func func;
        std::shared_ptr<Result<Res_>> res;
    };

    class ThreadPool {
    public:
        // 类型参数
        enum class Mode {
            FIXED,
            CACHED,
        };

        using TaskFunc = std::function<void()>;
        using ThreadPoolMode = ThreadPool::Mode;

        // 功能函数
        template<typename Func,typename ...Args>
        auto submitTask_(Func func,Args&&... params) -> std::shared_ptr<Result<decltype(func(std::forward<Args>(params)...))>>;

        void start();

        static size_t getDefaultInitThreadNum();

        static size_t getDefaultMaxThreadNum();

        static size_t getDefaultMaxTaskNum();

        static ThreadPoolMode getDefaultMode();

        void setInitThreadNum(size_t initThreadNum);

        void setMaxThreadNum(size_t maxThreadNum);

        void setMaxTaskNum(size_t maxTaskNum);

        void setMode(ThreadPoolMode mode);

        // 生命周期函数

        explicit ThreadPool(ThreadPoolMode mode = DEFAULT_MODE, size_t initThreadNum = DEFAULT_INIT_THREAD_NUM,
                   size_t maxThreadNum = DEFAULT_MAX_THREAD_NUM,size_t maxTaskNum = ThreadPool::DEFAULT_MAX_TASK_NUM_);

        ThreadPool(const ThreadPool&) = delete;
        ThreadPool& operator=(const ThreadPool&) = delete;

        ~ThreadPool();

    private:
//        辅助函数
        void submitTask_help(ThreadPool::TaskFunc task);
        void threadFunc(uint32_t id);
        void destroyThread(uint32_t id);
        bool addNewThread();
        void add_inited_Thread(uint32_t);

        // 配置
        static const size_t DEFAULT_INIT_THREAD_NUM;// 后面核心数的2/3
        static const size_t DEFAULT_MAX_THREAD_NUM;// 后面改为核心数
        static const size_t DEFAULT_MAX_TASK_NUM_;
        static const ThreadPoolMode DEFAULT_MODE;
        static const size_t DEFAULT_CACHEWAIT_MILLISECONDES;
        size_t cache_wait_milliseconds;

        // 和线程队列相关的
        std::unordered_map<uint32_t,std::shared_ptr<Thread>> threadQue_;
        size_t initThreadNum_ ;
        volatile std::atomic<size_t> nowThreadNum_{0};
        size_t maxThreadNum_;

        // 和任务队列相关的
        std::queue<TaskFunc> taskQue_;
        size_t maxTaskNum_;
        volatile std::atomic<size_t> nowTaskNum_{0};

        ThreadPoolMode mode;

        // 生产者消费者模型
        std::mutex mx_lock;
        std::mutex threadQue_mx_lock;
        std::condition_variable notFull_cv;
        std::condition_variable notEmpty_cv;
        std::condition_variable notThread_cv;
        volatile std::atomic_bool isEnd{false};
        volatile std::atomic_bool isRunning{false};
    };
    template<typename Func,typename ...Args>
    auto ThreadPool::submitTask_(Func func,Args&&... params) -> std::shared_ptr<Result<decltype(func(std::forward<Args>(params)...))>>{
        using ResType = decltype(func(std::forward<Args>(params)...));
        std::shared_ptr<Result<ResType>> res = std::make_shared<Result<ResType>>();
        auto ptr = std::make_shared<Task<ResType>>(std::bind(func,std::forward<Args>(params)...),res);
        this->submitTask_help([ptr](){ptr->exec();});
        return res;
    }

    ///////////////////////////////////////////////////////
    template<typename Ret_>
    void Task<Ret_>::exec(){
        if(this->res) this->res->set(this->func());
        else this->func();
    };

    template<>
    void Task<void>::exec();

    /////////////////////////////////////////////////////////////

    template<typename T>
    void Result<T>::set(const T&x) {
        this->data_ = x;
        this->sem_sp.post();
    }

    template<typename T>
    void Result<T>::set(T&&x) {
        this->data_ = std::move(x);
        this->sem_sp.post();

    }

    template<typename T>
    T Result<T>::get() {
        if (this->isReady)   return this->data_;
        else {
            this->sem_sp.wait();
            this->isReady = true;
            return this->data_;
        }
    }

    template<typename T>
    void Result<T>::setValid(bool isValid){
        this->isValid.store(isValid);
    };

    template<typename T>
    bool Result<T>::getValid(){
        return this->isValid.load();
    };

    /////////////////////////////////////////////////////////

    template<typename T>
    void CwjAny::setData(T data){
        this->data_ = std::make_shared<CwjAny::Derive<T>>(data);
    };

    template<typename T>
    T CwjAny::cast_() {
        auto one = dynamic_cast<Derive<T>*>(data_.get());
        if (one == nullptr) {
            throw std::runtime_error("CwjAny中存储的类型和要转化的类型不匹配");
        }
        return one->getData();
    }

}

#endif //THREADPOOL_THREADPOOL_H

